﻿// Copyright Wilfried Woivre - http://blog.woivre.fr

using System;
using System.Data.Services.Providers;
using System.Data.Services;
using Demo.TableStorageDataServices.Web.Models;

namespace Demo.TableStorageDataServices.Web.Services
{
    public abstract class BaseDataService<T> : DataService<T>, IServiceProvider where T : class, IDataSource
    {
        private readonly IDataServiceMetadataProvider _metadata;
        private readonly IDataServiceQueryProvider _query;
        private readonly IDataServiceUpdateProvider _update;

        protected BaseDataService()
        {
            _metadata = GetMetadataProvider();
            _query = new DataSourceQueryProvider<T>(_metadata);
            _update = new DataSourceUpdateProvider<T>(_metadata, _query);
        }

        public object GetService(Type serviceType)
        {
            if (serviceType == typeof(IDataServiceMetadataProvider))
                return _metadata;

            if (serviceType == typeof(IDataServiceQueryProvider))
                return _query;

            if (serviceType == typeof(IDataServiceUpdateProvider))
                return _update;

            return null;
        }

        public static IDataServiceMetadataProvider GetMetadataProvider()
        {
            var provider = new MetadataProvider();

            //var noteDeFraisType = new ResourceType(typeof(NoteDeFrais),
            //                           ResourceTypeKind.EntityType,
            //                           null,
            //                           "Namespace",
            //                           "NoteDeFrais",
            //                           false);

            //var noteDeFraisId = new ResourceProperty("Id",
            //                                         ResourcePropertyKind.Key | ResourcePropertyKind.Primitive,
            //                                         ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var enigmaType = new ResourceType(typeof(Enigma),
                                              ResourceTypeKind.EntityType,
                                              null,
                                              "Namespace",
                                              "Enigma",
                                              false);

            var enigmaAddress = new ResourceProperty("Address", ResourcePropertyKind.Primitive,
                                                     ResourceType.GetPrimitiveResourceType(typeof(string)));

            var enigmaId = new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive,
                                                ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var enigmaName = new ResourceProperty("Name", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            var enigmaCity = new ResourceProperty("City", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            var enigmaCountry = new ResourceProperty("Country", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            var enigmaPostalCode = new ResourceProperty("PostalCode", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            var enigmaLatitude = new ResourceProperty("Latitude", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(double)));

            var enigmaLongitude = new ResourceProperty("Longitude", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(double)));

            var enigmaIsFind = new ResourceProperty("IsFind", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(bool)));

            var enigmaPostDate = new ResourceProperty("PostDate", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(DateTime)));

            var enigmaUserId = new ResourceProperty("UserId", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var enigmaImage = new ResourceProperty("Image", ResourcePropertyKind.Primitive,
                                                   ResourceType.GetPrimitiveResourceType(typeof(byte[])));

            var enigmaUrlImage = new ResourceProperty("UrlImage", ResourcePropertyKind.Primitive,
                                                      ResourceType.GetPrimitiveResourceType(typeof (string)));


            enigmaType.AddProperty(enigmaAddress);
            enigmaType.AddProperty(enigmaCity);
            enigmaType.AddProperty(enigmaCountry);
            enigmaType.AddProperty(enigmaId);
            enigmaType.AddProperty(enigmaIsFind);
            enigmaType.AddProperty(enigmaLatitude);
            enigmaType.AddProperty(enigmaLongitude);
            enigmaType.AddProperty(enigmaName);
            enigmaType.AddProperty(enigmaPostalCode);
            enigmaType.AddProperty(enigmaPostDate);
            enigmaType.AddProperty(enigmaUserId);
            enigmaType.AddProperty(enigmaImage);
            enigmaType.AddProperty(enigmaUrlImage);
            var enigmaSet = new ResourceSet("Enigmas", enigmaType);

            provider.AddResourceType(enigmaType);
            provider.AddResourceSet(enigmaSet);

            var responseType = new ResourceType(typeof(Response),
                                              ResourceTypeKind.EntityType,
                                              null,
                                              "Namespace",
                                              "Response",
                                              false);

            var responseId = new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive,
                                                ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var responseUserId = new ResourceProperty("UserId", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var responseEnigmaId = new ResourceProperty("EnigmaId", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var responsePostDate = new ResourceProperty("PostDate", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(DateTime)));

            var responseContent = new ResourceProperty("Content", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            var responseIsExact = new ResourceProperty("IsExact", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(bool)));

            responseType.AddProperty(responseContent);
            responseType.AddProperty(responseEnigmaId);
            responseType.AddProperty(responseId);
            responseType.AddProperty(responseIsExact);
            responseType.AddProperty(responsePostDate);
            responseType.AddProperty(responseUserId);

            var responseSet = new ResourceSet("Responses", responseType);

            provider.AddResourceType(responseType);
            provider.AddResourceSet(responseSet);

            var userType = new ResourceType(typeof(User),
                                              ResourceTypeKind.EntityType,
                                              null,
                                              "Namespace",
                                              "User",
                                              false);

            var userId = new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive,
                                                ResourceType.GetPrimitiveResourceType(typeof(Guid)));

            var userLastName = new ResourceProperty("LastName", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));


            var userFirstName = new ResourceProperty("FirstName", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));


            var userEmail = new ResourceProperty("Email", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));


            var userPassword = new ResourceProperty("Password", ResourcePropertyKind.Primitive,
                                                  ResourceType.GetPrimitiveResourceType(typeof(string)));

            userType.AddProperty(userEmail);
            userType.AddProperty(userFirstName);
            userType.AddProperty(userId);
            userType.AddProperty(userLastName);
            userType.AddProperty(userPassword);

            var userSet = new ResourceSet("Users", userType);
            provider.AddResourceType(userType);
            provider.AddResourceSet(userSet);



            return provider;

        }
    }
}
